//
//  KLUtils.m
//  Base
//
//  Created by zhusanbao on 2020/10/18.
//

#import "KLUtils.h"
#import "UINavigationComponent.h"
#import <objc/runtime.h>

@implementation KLUtils

#pragma mark - sw
//替换对象方法
void replaceInstanceMethods(Class className,SEL newSEL,SEL origSEL){
    Method orig = class_getInstanceMethod(className, origSEL);
    Method new = class_getInstanceMethod(className, newSEL);
    if(class_addMethod(className, origSEL, method_getImplementation(new), method_getTypeEncoding(new)))
    {
        class_replaceMethod(className, newSEL, method_getImplementation(orig), method_getTypeEncoding(orig));
    }else {
        method_exchangeImplementations(orig, new);
    }
}

//替换类方法
void replaceClassMethods(Class className,SEL newSEL,SEL origSEL){
    Method orig = class_getClassMethod(className, origSEL);
    Method new = class_getClassMethod(className, newSEL);
    method_exchangeImplementations(orig, new);
}

BOOL showController(UIViewController *vc,BOOL animated,void (^completion)(void)){
    @try {
        UIViewController *controller = [[[UIApplication sharedApplication].delegate window] rootViewController];
        if (!controller) {
            return NO;
        }
        if ([controller isKindOfClass:[UINavigationController class]]) {
            [(UINavigationController*)controller pushViewController:vc animated:animated completion:completion];
            return YES;
        }else if([controller isKindOfClass:[UITabBarController class]]){
            UIViewController *selectController = [(UITabBarController*)controller selectedViewController];
            
            if ([selectController isKindOfClass:[UINavigationController class]]) {
                UINavigationController* nav = (UINavigationController*)selectController;
                
                UIViewController *pCtr = [nav presentedViewController];
                while ([pCtr presentedViewController]!=nil) {
                    pCtr = [pCtr presentedViewController];
                }
                if (pCtr) {
                    if ([pCtr isKindOfClass:[UINavigationController class]]) {
                        [(UINavigationController*)pCtr pushViewController:vc animated:animated completion:completion];
                    }else{
                        [pCtr presentViewController:vc animated:YES completion:nil];
                    }
                }else{
                    [nav pushViewController:vc animated:animated completion:completion];
                }
                return YES;
            }else{
                UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
                [selectController presentViewController:nav animated:animated completion:completion];
                return YES;
            }
        }else if ([controller.presentedViewController isKindOfClass:UINavigationController.class]){
            [(UINavigationController*)controller.presentedViewController pushViewController:vc animated:animated completion:completion];
            return YES;
        }else{
            UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
            nav.modalPresentationStyle = UIModalPresentationFullScreen;
            [controller presentViewController:nav animated:YES completion:completion];
            return YES;
        }
        return NO;
    } @catch (NSException *exception) {
        
    } @finally {
        
    }
}
BOOL replaceController(UIViewController *fromVc, UIViewController *toVc, BOOL animate,void (^_Nullable completion)(void)){
    UINavigationController *navgation = fromVc.navigationController;
    if (navgation) {
        NSMutableArray *vcs= [NSMutableArray arrayWithArray:navgation.viewControllers];
        [vcs removeObject:fromVc];
        if (toVc) {[vcs addObject:toVc];}
        [navgation setViewControllers:vcs animated:animate completion:completion];
        return YES;
    }else {
#if DEBUG
        klAlert(nil, [NSString stringWithFormat:@"%@没有导航栈",fromVc], @[@"确定"], nil);
#endif
        return NO;
    }
}
BOOL replaceControllers(NSArray <UIViewController *>*fromVcs, UIViewController *_Nullable toVc, BOOL animate,void (^_Nullable completion)(void)){
    if (fromVcs.count == 0) {return NO;}
    UINavigationController *navgation = fromVcs.firstObject.navigationController;
    if (navgation) {
        NSMutableArray *vcs= [NSMutableArray arrayWithArray:navgation.viewControllers];
        [vcs removeObjectsInArray:fromVcs];
        if (toVc) {[vcs addObject:toVc];}
        [navgation setViewControllers:vcs animated:animate completion:completion];
        return YES;
    }else {
#if DEBUG
        klAlert(nil, [NSString stringWithFormat:@"%@没有导航栈",fromVcs.description], @[@"确定"], nil);
#endif
        return NO;
    }
}
BOOL replaceLastController(UIViewController *fromVc, UIViewController *toVc, BOOL animate,void (^_Nullable completion)(void)){
    UINavigationController *navgation = fromVc.navigationController;
    if (navgation) {
        NSMutableArray *vcs= [NSMutableArray arrayWithArray:navgation.viewControllers];
        if (vcs.count) {[vcs removeLastObject];}
        if (toVc) {[vcs addObject:toVc];}
        [navgation setViewControllers:vcs animated:animate completion:completion];
        return YES;
    }else {
#if DEBUG
        klAlert(nil, [NSString stringWithFormat:@"%@没有导航栈",fromVc], @[@"确定"], nil);
#endif
        return NO;
    }
}
UINavigationController *currentNavigationController(){
    UIViewController *controller = [[[UIApplication sharedApplication].delegate window] rootViewController];
    if ([controller isKindOfClass:[UINavigationController class]]) {
        return (UINavigationController*)controller;
    }else if([controller isKindOfClass:[UITabBarController class]]){
        UIViewController *selectController = [(UITabBarController*)controller selectedViewController];
        if ([selectController isKindOfClass:[UINavigationController class]]) {
            UINavigationController *nav = (UINavigationController*)selectController;
            if ([nav.presentedViewController isKindOfClass:UINavigationController.class]) {
                return (UINavigationController*)nav.presentedViewController;
            }
            return nav;
        }
    }
    return nil;
}


UIViewController *currentTopViewController(){
    UIViewController* viewController = [UIApplication sharedApplication].delegate.window.rootViewController;
    return findBestViewController(viewController);
}

UIViewController *findBestViewController(UIViewController *vc){
    if (vc.presentedViewController) {
        return findBestViewController(vc.presentedViewController);
    }else if([vc isKindOfClass:[UISplitViewController class]]){
        UISplitViewController* svc = (UISplitViewController*) vc;
        if (svc.viewControllers.count > 0){
            return findBestViewController(svc.viewControllers.lastObject);
        }else{
            return vc;
        }
    }else if ([vc isKindOfClass:[UINavigationController class]]) {
        UINavigationController* svc = (UINavigationController*)vc;
        if (svc.viewControllers.count > 0){
            return findBestViewController(svc.topViewController);
        }else{
            return vc;
        }
    }else if ([vc isKindOfClass:[UITabBarController class]]) {
        UITabBarController* svc = (UITabBarController*) vc;
        if (svc.viewControllers.count > 0){
            return findBestViewController(svc.selectedViewController);
        }else{
            return vc;
        }
    }else{
        return vc;
    }
}

void klAlertTextFiled(NSString *title, NSString *msg, NSArray *tfblocks, NSArray *btns, void(^complete)(NSInteger idx)){
    UIAlertController *alertCtl = [UIAlertController alertControllerWithTitle:title ?: @"提示" message:msg preferredStyle:(UIAlertControllerStyleAlert)];
    [tfblocks enumerateObjectsUsingBlock:^(void(^obj)(UITextField *tf), NSUInteger idx, BOOL * _Nonnull stop) {
        [alertCtl addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
            if (obj) {obj(textField);}
        }];
    }];
    [btns enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        UIAlertActionStyle style = ([obj isEqualToString:@"取消"] || [obj isEqualToString:@"退出"]) ? UIAlertActionStyleCancel : UIAlertActionStyleDefault;
        [alertCtl addAction:[UIAlertAction actionWithTitle:obj style:style handler:^(UIAlertAction * _Nonnull action) {
            if (complete) {complete(idx);}
        }]];
    }];
    [currentTopViewController() presentViewController:alertCtl animated:YES completion:nil];
}

void klAlert(NSString *title, NSString *msg, NSArray *titles, void(^complete)(NSInteger idx)){
    UIAlertController *alertCtl = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:(UIAlertControllerStyleAlert)];
    if (titles) {
        if ([titles isKindOfClass:NSString.class]) {
            UIAlertActionStyle style = ([(id)titles isEqualToString:@"取消"] || [(id)titles isEqualToString:@"退出"]) ? UIAlertActionStyleCancel : UIAlertActionStyleDefault;
            [alertCtl addAction:[UIAlertAction actionWithTitle:(id)titles style:style handler:^(UIAlertAction * _Nonnull action) {
                if (complete) {complete(0);}
            }]];
        }else{
            [titles enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                UIAlertActionStyle style = ([obj isEqualToString:@"取消"] || [obj isEqualToString:@"退出"]) ? UIAlertActionStyleCancel : UIAlertActionStyleDefault;
                [alertCtl addAction:[UIAlertAction actionWithTitle:obj style:style handler:^(UIAlertAction * _Nonnull action) {
                    if (complete) {complete(idx);}
                }]];
            }];
        }
    }else{
        [alertCtl addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            if (complete) {complete(0);}
        }]];
    }
    [currentTopViewController() presentViewController:alertCtl animated:YES completion:nil];
}

void klActions(NSString *title, NSString *msg, NSArray *titles, void(^complete)(NSInteger idx)){
    UIAlertController *alertCtl = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:(UIAlertControllerStyleActionSheet)];
    [titles enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        UIAlertActionStyle style = ([obj isEqualToString:@"取消"] || [obj isEqualToString:@"退出"]) ? UIAlertActionStyleCancel : UIAlertActionStyleDefault;
        [alertCtl addAction:[UIAlertAction actionWithTitle:obj style:style handler:^(UIAlertAction * _Nonnull action) {
            if (complete) {complete(idx);}
        }]];
    }];
    [currentTopViewController() presentViewController:alertCtl animated:YES completion:nil];
}

@end
